﻿using Entity;
using Microsoft.AspNetCore.Http;
using ServiceCore;
using ServiceCore.Tool.NPOI;
using ServiceCore.Tool.Pic;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using System.Web;



namespace Customer.Bussiness_Service
{ 
    public interface Imateriel_service
    {
        /// <summary>
        /// 设置物料类型
        /// </summary>
        /// <param name="materiel_type_id"></param>
        /// <param name="type_name"></param>
        /// <param name="parent_id"></param>
        /// <returns></returns>
        ResultObjModel save_materiel_type(string materiel_type_id, string type_name, string parent_id = "0");
        /// <summary>
        /// 根据上级ID获取列表信息
        /// </summary>
        /// <param name="parnet_id"></param>
        /// <returns></returns>
        ResultObjModel get_materiel_type_list(string parent_id);
        /// <summary>
        /// 获取物料类型
        /// </summary>
        /// <param name="only_can_use"></param>
        /// <returns></returns>
        ResultObjModel get_materiel_type_tree(bool only_can_use = false);
        /// <summary>
        /// 设置物料类型可用状态
        /// </summary>
        /// <param name="only_can_use"></param>
        /// <returns></returns>
        ResultObjModel set_materiel_type_state(string materiel_type_id, materiel_type_state? materiel_type_state);

        /// <summary>
        /// 保存物料信息
        /// </summary>
        /// <param name="Params"></param>
        /// <returns></returns>
        ResultObjModel save_materiel(materiel_base Params);
        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        ResultListModel<search_materiel_base> get_materiel_pagelist(materiel_base_query query);
        /// <summary>
        /// 设置状态
        /// </summary>
        /// <param name="materiel_id"></param>
        /// <param name="materiel_base_state"></param>
        /// <returns></returns>
        ResultObjModel set_materiel_state(string materiel_id, materiel_base_state? materiel_base_state);
        /// <summary>
        /// 根据完整物料编号获取物料详情
        /// </summary>
        /// <param name="materiel_total_show_no"></param>
        /// <returns></returns>
        ResultObjModel get_materiel_model(string materiel_total_show_no);
    }
    public class materiel_service : Imateriel_service
    {
        private readonly IToole_DI _tool;
        private readonly IHttpContextAccessor _context;
        private readonly ICacheHelper _cache;

        public materiel_service(IToole_DI Tool, IHttpContextAccessor Context, ICacheHelper Cache)
        {
            _tool = Tool;
            _context = Context;
            _cache = Cache;
        }

        #region 物料类型管理 
        public ResultObjModel save_materiel_type(string materiel_type_id, string type_name, string parent_id = "0")
        {
            return CoreStartDo.ResultAction(result =>
            {
                if (string.IsNullOrWhiteSpace(type_name))
                {
                    result.code = 1;
                    result.msg = "类型名称不能为空";
                    return result;
                }
                if (string.IsNullOrWhiteSpace(parent_id))
                {
                    parent_id = "0";
                }
                int tran_rows = 0;
                if (string.IsNullOrWhiteSpace(materiel_type_id))
                {
                    //新增数据,直接开始拼接添加数据
                    materiel_type new_mod = new materiel_type();
                    new_mod.addtime = DateTime.Now;
                    new_mod.adduser = _tool.di_user.USER.uid;
                    new_mod.materiel_type_name = type_name;
                    new_mod.parent_id = parent_id;
                    new_mod.materiel_type_state = materiel_type_state.启用;
                    if (parent_id == "0")
                    {
                        //现在处理的是最上级数据直接开始拼就可以了
                        new_mod.lv = 1;//第一级 
                        //获取所有最上级数据的数量 然后+1  获取最大值  因为不允许删除 所以可以这么干
                        int max_count = _tool.di_db.GetList<int>("select count(*) from materiel_type where parent_id=@parent_id", new { parent_id }).FirstOrDefault();
                        new_mod.materiel_type_no = max_count + 1;
                        new_mod.materiel_type_id = new_mod.materiel_type_no.ToString("000");
                    }
                    else
                    {
                        //妙  现在处理的不是最上级数据 那么先获取他上级数据的信息
                        materiel_type parent_mod = _tool.di_db.GetList<materiel_type>("select * from materiel_type where materiel_type_id=@parent_id", new { parent_id }).FirstOrDefault();
                        if (parent_mod == null)
                        {
                            result.code = 1;
                            result.msg = "所选上级类型不存在";
                            return result;
                        }
                        new_mod.lv = parent_mod.lv + 1;
                        //获取所有最上级数据的数量 然后+1  获取最大值  因为不允许删除 所以可以这么干
                        int max_count = _tool.di_db.GetList<int>("select count(*) from materiel_type where parent_id=@parent_id", new { parent_id }).FirstOrDefault();
                        new_mod.materiel_type_no = max_count + 1;
                        new_mod.materiel_type_id = parent_mod.materiel_type_id + "." + new_mod.materiel_type_no.ToString("000");
                    }
                    tran_rows = _tool.di_db.Add(new_mod);
                }
                else
                {
                    //根据materiel_type_id修改名称 其他的东西都不允许变
                    materiel_type update_item = _tool.di_db.GetList<materiel_type>("select top 1 * from materiel_type where materiel_type_id=@materiel_type_id", new { materiel_type_id }).FirstOrDefault();
                    if (update_item == null)
                    {
                        result.code = 1;
                        result.msg = "待修改项不存在";
                        return result;
                    }
                    update_item.materiel_type_name = type_name;
                    tran_rows = _tool.di_db.Update<materiel_type>(new string[] { "materiel_type_name" }, new string[] { "materiel_type_id=@materiel_type_id" }, update_item);
                }
                if (tran_rows > 0)
                {
                    result.code = 0;
                    result.msg = "保存成功";
                    _cache.RemoveCache("get_materiel_type_tree");
                    _cache.RemoveCache("get_materiel_type_tree_only_can_use");
                    _tool.ref_materiel_list();
                }
                else
                {
                    result.code = 1;
                    result.msg = "保存失败";
                }
                return result;
            });
        }

        public ResultObjModel get_materiel_type_list(string parent_id)
        {

            return CoreStartDo.ResultAction(result =>
            {
                if (string.IsNullOrWhiteSpace(parent_id))
                {
                    parent_id = "0";
                }
                result.code = 0;
                result.msg = "success";
                result.data = _tool.get_materiel_list.Where(s => s.parent_id == parent_id).ToList();
                return result;
            });
        }
        /// <summary>
        /// 获取一个整体树形图
        /// </summary>
        /// <returns></returns>
        public ResultObjModel get_materiel_type_tree(bool only_can_use = false)
        {
            return CoreStartDo.ResultAction(result =>
            {

                if (!only_can_use)
                {
                    string cache_key = $"get_materiel_type_tree";
                    if (_cache.Exists(cache_key))
                    {
                        result = _cache.GetCache<ResultObjModel>(cache_key);
                        result.msg = "success by cache<get_materiel_type_tree>";
                        return result;
                    }
                    else
                    {
                        ///总之先给所有数据都拿下来 
                        List<materiel_type> all_type = _tool.get_materiel_list;
                        ///定义树容器
                        List<materiel_type_tree_model> tree = get_tree_next(all_type, "0");
                        result.code = 0;
                        result.msg = "success";
                        result.data = tree;
                        _cache.SetCache(cache_key, result, DateTimeOffset.Now.AddDays(1));
                    }
                }
                else
                {
                    string cache_key = $"get_materiel_type_tree_only_can_use";
                    if (_cache.Exists(cache_key))
                    {
                        result = _cache.GetCache<ResultObjModel>(cache_key);
                        result.msg = "success by cache<get_materiel_type_tree_only_can_use>";
                        return result;
                    }
                    else
                    {
                        ///总之先给所有数据都拿下来
                        List<materiel_type> all_type = _tool.get_materiel_list.Where(s => s.materiel_type_state == materiel_type_state.启用).ToList();
                        ///定义树容器
                        List<materiel_type_tree_model> tree = get_tree_next(all_type, "0");
                        result.code = 0;
                        result.msg = "success";
                        result.data = tree;
                        _cache.SetCache(cache_key, result, DateTimeOffset.Now.AddDays(1));
                    }
                }
                return result;
            });
        }
        private List<materiel_type_tree_model> get_tree_next(List<materiel_type> all_type, string parent_id)
        {
            List<materiel_type_tree_model> next_tree = new List<materiel_type_tree_model>();
            foreach (var item in all_type.Where(s => s.parent_id == parent_id))
            {
                materiel_type_tree_model additem = new materiel_type_tree_model();
                additem.materiel_type_id = item.materiel_type_id;
                additem.materiel_type_name = item.materiel_type_name;
                additem.parent_id = item.parent_id;
                additem.materiel_type_state = item.materiel_type_state;
                additem.children = get_tree_next(all_type, item.materiel_type_id);
                next_tree.Add(additem);
            }
            return next_tree;
        }
        /// <summary>
        /// 设置物料类型可用状态
        /// </summary>
        /// <returns></returns>
        public ResultObjModel set_materiel_type_state(string materiel_type_id, materiel_type_state? materiel_type_state)
        {
            return CoreStartDo.ResultAction(result =>
            {
                if (string.IsNullOrWhiteSpace(materiel_type_id))
                {
                    result.code = 1;
                    result.msg = "物料类型id不能为空";
                    return result;
                }
                if (!materiel_type_state.HasValue)
                {
                    result.code = 1;
                    result.msg = "物料类型状态不能为空";
                    return result;
                }
                //直接更改对应物料类型状态
                int rows = _tool.di_db.Update<materiel_type>(new string[] { "materiel_type_state" }, new string[] { "materiel_type_id=@materiel_type_id" }, new { materiel_type_id, materiel_type_state });
                if (rows > 0)
                {
                    result.code = 0;
                    result.msg = "设置成功";
                    _cache.RemoveCache("get_materiel_type_tree");
                    _cache.RemoveCache("get_materiel_type_tree_only_can_use");
                    _tool.ref_materiel_list();
                }
                else
                {
                    result.code = 1;
                    result.msg = "设置失败";
                }
                return result;
            });
        }
        #endregion 
        #region 物料 
        public ResultObjModel save_materiel(materiel_base Params)
        {
            return CoreStartDo.ResultAction(result =>
            {
                if (string.IsNullOrWhiteSpace(Params.materiel_name))
                {
                    result.code = 1;
                    result.msg = "物料名称不能为空";
                    return result;
                }
                if (string.IsNullOrWhiteSpace(Params.materiel_id))
                {
                    Params.materiel_id = "";
                }
                var check_same_name = _tool.di_db.GetList<int>("select count(*) from materiel_base where materiel_name=@materiel_name and materiel_id<>@materiel_id", Params).FirstOrDefault();
                if (check_same_name > 0)
                {
                    result.code = 1;
                    result.msg = "物料名称已存在";
                    return result;
                }
                string create_no = !string.IsNullOrWhiteSpace(Params.materiel_type_three) ? Params.materiel_type_three :
                                         !string.IsNullOrWhiteSpace(Params.materiel_type_two) ? Params.materiel_type_two + "000" :
                                             !string.IsNullOrWhiteSpace(Params.materiel_type_one) ? Params.materiel_type_one + "000.000" :
                                                 "000.000.000";
                int tran_rows = 0;
                if (string.IsNullOrWhiteSpace(Params.materiel_id))
                {
                    //添加的时候需要生成物料流水号 
                    _tool.get_materiel_no_queue_in();
                    int add_no = _tool.get_materiel_no_queue_out;
                    Params.materiel_id = _tool.di_getid.IGet_SnowFlake_Id;
                    if (add_no < 1000)
                    {
                        Params.materiel_show_no = add_no.ToString("000");
                    }
                    else
                    {
                        Params.materiel_show_no = add_no.ToString();
                    }
                    Params.materiel_total_show_no = create_no + '.' + Params.materiel_show_no;
                    Params.addtime = DateTime.Now;
                    Params.adduser = _tool.di_user.USER.uid;
                    Params.materiel_base_state = materiel_base_state.启用;
                    tran_rows = _tool.di_db.Add(Params);
                }
                else
                {
                    //编辑的时候 先检测是否存在 需要用自身的流水号再重新生成展示编号
                    var updateitem = _tool.di_db.GetList<materiel_base>("select top 1 * from materiel_base where materiel_id=@materiel_id", new { Params.materiel_id }).FirstOrDefault();
                    if (updateitem == null)
                    {
                        result.code = 1;
                        result.msg = "待修改项不存在";
                        return result;
                    }
                    Params.materiel_show_no = updateitem.materiel_show_no;
                    Params.materiel_total_show_no = create_no + '.' + updateitem.materiel_show_no;

                    tran_rows = _tool.di_db.Update<materiel_base>(new string[] {
                        "materiel_name","materiel_type_one","materiel_type_two","materiel_type_three","materiel_pic","materiel_show_no","materiel_total_show_no","specifications","unit","use_des"
                    }, new string[] {
                        "materiel_id=@materiel_id"
                    }, Params);
                }
                if (tran_rows > 0)
                {
                    result.code = 0;
                    result.msg = "保存成功";
                }
                else
                {
                    result.code = 1;
                    result.msg = "保存失败";
                }
                return result;
            });
        }
        /// <summary>
        /// 搜索
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public ResultListModel<search_materiel_base> get_materiel_pagelist(materiel_base_query query)
        {
            return CoreStartDo.ResultAction<ResultListModel<search_materiel_base>>(result =>
            {
                string sql = "select * from materiel_base";
                string where = " where 1=1";
                dynamic query_dy = new System.Dynamic.ExpandoObject();
                if (!string.IsNullOrWhiteSpace(query.materiel_type_one))
                {
                    where += " and materiel_type_one=@materiel_type_one";
                    query_dy.materiel_type_one = query.materiel_type_one;
                }
                if (!string.IsNullOrWhiteSpace(query.materiel_type_two))
                {
                    where += " and materiel_type_two=@materiel_type_two";
                    query_dy.materiel_type_two = query.materiel_type_two;
                }
                if (!string.IsNullOrWhiteSpace(query.materiel_type_three))
                {
                    where += " and materiel_type_three=@materiel_type_three";
                    query_dy.materiel_type_three = query.materiel_type_three;
                }
                if (!string.IsNullOrWhiteSpace(query.specifications))
                {
                    where += " and specifications like @specifications";
                    query_dy.specifications = $"%{ query.specifications }%";
                }
                if (query.search_type.HasValue)
                {
                    switch (query.search_type.Value)
                    {
                        case materiel_base_search_enum.物料编号:
                            where += " and materiel_total_show_no like @materiel_total_show_no";
                            query_dy.materiel_total_show_no = $"%{ query.search_value }%";
                            break;
                        case materiel_base_search_enum.物料名称:
                            where += " and materiel_name like @materiel_name";
                            query_dy.materiel_name = $"%{ query.search_value }%";
                            break;
                    }
                }
                result = _tool.di_db.GetPageList<search_materiel_base>(sql, where, "addtime", query_dy, query.IsPage, query.page, query.pagesize);
                foreach (var item in result.rows)
                {
                    item.materiel_type_one_str = _tool.get_materiel_list.Where(s => s.materiel_type_id == item.materiel_type_one).Any() ? _tool.get_materiel_list.Where(s => s.materiel_type_id == item.materiel_type_one).FirstOrDefault().materiel_type_name : "";
                    item.materiel_type_two_str = _tool.get_materiel_list.Where(s => s.materiel_type_id == item.materiel_type_two).Any() ? _tool.get_materiel_list.Where(s => s.materiel_type_id == item.materiel_type_two).FirstOrDefault().materiel_type_name : "";
                    item.materiel_type_three_str = _tool.get_materiel_list.Where(s => s.materiel_type_id == item.materiel_type_three).Any() ? _tool.get_materiel_list.Where(s => s.materiel_type_id == item.materiel_type_three).FirstOrDefault().materiel_type_name : "";
                }
                return result;
            });
        }
        /// <summary>
        /// 设置物料状态
        /// </summary>
        /// <returns></returns>
        public ResultObjModel set_materiel_state(string materiel_id, materiel_base_state? materiel_base_state)
        {
            return CoreStartDo.ResultAction(result =>
            {
                if (string.IsNullOrWhiteSpace(materiel_id))
                {
                    result.code = 1;
                    result.msg = "物料ID不能为空";
                    return result;
                }
                if (!materiel_base_state.HasValue)
                {
                    result.code = 1;
                    result.msg = "必须设置物料状态";
                    return result;
                }
                materiel_base check_item = _tool.di_db.GetList<materiel_base>("select top 1 * from materiel_base where materiel_id=@materiel_id", new { materiel_id }).FirstOrDefault();
                if (check_item == null)
                {
                    result.code = 1;
                    result.msg = "未找到物料信息";
                    return result;
                }
                int set_row = _tool.di_db.do_Execute("update materiel_base set materiel_base_state=@materiel_base_state where materiel_id=@materiel_id", new { materiel_base_state, materiel_id });
                if (set_row > 0)
                {
                    result.code = 0;
                    result.msg = "设置成功";
                }
                else
                {
                    result.code = 1;
                    result.msg = "设置失败";
                }
                return result;
            });
        }
        /// <summary>
        /// 根据完全编号获取物料详情
        /// </summary>
        /// <returns></returns>
        public ResultObjModel get_materiel_model(string materiel_total_show_no)
        {
            return CoreStartDo.ResultAction(result =>
            {
                if (string.IsNullOrWhiteSpace(materiel_total_show_no) || materiel_total_show_no.Replace(".", "").Length != 12)
                {
                    result.code = 1;
                    result.msg = "关键参数未入参或不合法";
                    return result;
                }
                //根据完整数据返回数据
                var materiel_base = _tool.di_db.GetList<materiel_base>("select top 1 * from materiel_base where materiel_total_show_no=@materiel_total_show_no", new { materiel_total_show_no }).FirstOrDefault();
                if (materiel_base == null)
                {
                    result.code = 1;
                    result.msg = "物料信息不存在";
                    return result;
                }
                result.code = 0;
                result.msg = "success";
                result.data = materiel_base;
                return result;
            });
        }
        #endregion
    }
}
